package tec;
import java.util.HashSet;
import java.util.Iterator;

class Autobus implements Bus
{

	private HashSet<Passager> passagers;
	private JaugeNaturel jaugeAssis;
	private JaugeNaturel jaugeDebout;
	protected int arretActuel;
	private Iterator<Passager> index;

	public Autobus(int nbAssis, int nbDebout) 
	{
		if(nbAssis < 0 || nbDebout < 0)
			throw new IllegalArgumentException("nombre de passager negatif");

		jaugeAssis = new JaugeNaturel(-1,nbAssis,0);
		jaugeDebout = new JaugeNaturel(-1,nbDebout,0);
		arretActuel = 0;
		passagers = new HashSet<Passager>(nbAssis+nbDebout);
	}


	public boolean aPlaceAssise () 
	{
		return !jaugeAssis.estRouge();
	} 	

	public boolean aPlaceDebout () 
	{
		return !jaugeDebout.estRouge();
	}

	public void allerArretSuivant() throws TecInvalidException 
	{
		index = passagers.iterator();
		Autobus b = new Autobus(0,0){
			public void demanderSortie(Passager p){
				super.demanderSortie(index, p);
			}
		};
		arretActuel++;

		while(index.hasNext())
			index.next().nouvelArret(b, arretActuel);
	}

	public void demanderChangerEnAssis(Passager p) 
	{
		if(p.estAssis())
			throw new IllegalStateException("passager deja assis");
		if(!jaugeAssis.estRouge()){
			jaugeAssis.incrementer();
			jaugeDebout.decrementer();
			p.accepterPlaceAssise();
		}	
	}

	public void demanderChangerEnDebout(Passager p)
	{
		if(p.estDebout())
			throw new IllegalStateException("passager deja debout");

		if(!jaugeDebout.estRouge()){
			jaugeDebout.incrementer();
			jaugeAssis.decrementer();
			p.accepterPlaceDebout();
		}
	}

	public void demanderPlaceAssise(Passager p) 
	{
		if(p.getDestination() <= arretActuel)
			throw new IllegalStateException("destination depassee");

		if(!jaugeAssis.estRouge()){
			jaugeAssis.incrementer();
			passagers.add(p);
			p.accepterPlaceAssise();
		}
	}

	public void demanderPlaceDebout(Passager p) 
	{
		if(p.getDestination() <= arretActuel)
			throw new IllegalStateException("destination depasse");

		if(!jaugeDebout.estRouge()){
			jaugeDebout.incrementer();
			passagers.add(p);
			p.accepterPlaceDebout();
		}
	}

	private void demanderSortie(Iterator<Passager> index, Passager p){
		if(p.estDehors())
			throw new IllegalStateException("passager déjà dehors");

		if(p.estAssis())
			jaugeAssis.decrementer();
		else if (p.estDebout())
			jaugeDebout.decrementer();
		
		index.remove();	
		p.accepterSortie();
	}


	public void demanderSortie(Passager p) 
	{
		if(p.estDehors())
			throw new IllegalStateException("passager déjà dehors");

		if(p.estAssis())
			jaugeAssis.decrementer();
		else if (p.estDebout())
			jaugeDebout.decrementer();
		
		passagers.remove(p);	
		p.accepterSortie();
	}

	@Override
	public String toString()
	{
		return "[arret:" + arretActuel + ", assis:" 
			+ jaugeAssis.toString() + ", debout:" 
			+ jaugeDebout.toString() + "]";
	}
}


